package com.jrx.anytxn.accounting.job.voucherFile.config;


import com.jrx.anytxn.accounting.config.VoucherFileConfig;
import com.jrx.anytxn.accounting.constant.AccountBizConstant;
import com.jrx.anytxn.accounting.job.voucherFile.step.MergeVoucherListener;
import com.jrx.anytxn.common.uitl.DateUtils;
import com.jrx.anytxn.param.entity.PrOrganizationTable;
import com.jrx.anytxn.param.service.system.IOrganizationTableService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Paths;


/**
 * 合并传票文件
 */
@Configuration
@EnableConfigurationProperties(VoucherFileConfig.class)
public class MergeVoucherFileConfiguration {

    private static final Logger logger = LoggerFactory.getLogger(MergeVoucherFileConfiguration.class);


    @Autowired
    public JobBuilderFactory jobBuilderFactory;
    @Autowired
    public StepBuilderFactory stepBuilderFactory;
    @Autowired
    private VoucherFileConfig voucherFileConfig;
    @Autowired
    private IOrganizationTableService organizationTableService;
    @Autowired
    private MergeVoucherListener mergeVoucherListener;

    @Bean
    public Job mergeVoucherFileJob(){
        return jobBuilderFactory.get("mergeVoucherFileJob").incrementer(new RunIdIncrementer()).listener(mergeVoucherListener)
                .start(mergeVoucherFileStep())
                .build();
    }

    @Bean
    public Step mergeVoucherFileStep(){
        return stepBuilderFactory.get("mergeVoucherFileStep")
                .tasklet(mergeVoucherFileStepTasklet())
                .build();
    }

    @Bean
    @StepScope
    public Tasklet mergeVoucherFileStepTasklet() {
        return (stepContribution, chunkContext) -> {
            logger.debug("分库文件合并开始。。。。。。");
            String basePath = voucherFileConfig.getVoucherPath();

            PrOrganizationTable org = organizationTableService.findByOrgIdForBatch(AccountBizConstant.ORG);
            String today = DateUtils.format(org.getToday(),"yyyyMMdd");

            String filePath = basePath + org.getTenantId() + File.separator + today + File.separator;

            File file = new File(filePath);
            File[] tempList = file.listFiles();
            if(tempList == null || tempList.length == 0){
                logger.error("文件合并，未获取到需要合并的文件");
                throw new RuntimeException("文件合并，未获取到需要合并的文件");
            }

            //最后目标文件
            File resultFile = new File(filePath + AccountBizConstant.VOUCHER_FILE_TYPE + "_" + today + ".txt");
            Boolean isNullFile = true;
            try (FileChannel resultFileChannel = new FileOutputStream(resultFile, true).getChannel()){
                for(int i = 0; i < tempList.length; i++){
                    FileChannel blk = new FileInputStream(tempList[i]).getChannel();
                    if(i == 0 && blk.size() == 0){
                        resultFile.createNewFile();
                    }else if (blk.size() != 0){
                        if(!isNullFile && i != 0){
                            //换行
                            ByteBuffer buf = ByteBuffer.allocate(48);
                            buf.clear();
                            buf.put("\r\n".getBytes());
                            buf.flip();
                            while(buf.hasRemaining()) {
                                resultFileChannel.write(buf);
                            }
                        }
                        resultFileChannel.transferFrom(blk, resultFileChannel.size(), blk.size());
                        isNullFile = false;
                    }
                    blk.close();
                }
            } catch (IOException e) {
                logger.error("传票文件合并异常，异常信息：",e);
                throw new RuntimeException(e);
            }

            // 获取文件总条数
            Long count = null;
            try {
                count = Files.lines(Paths.get(filePath + AccountBizConstant.VOUCHER_FILE_TYPE + "_" + today + ".txt")).count();
            } catch (IOException e) {
                logger.error("读取文件条数异常：",e);
                throw new RuntimeException(e);
            }
            // 生成OK文件
            File okFile = new File(filePath + AccountBizConstant.VOUCHER_FILE_TYPE + "_" + today + ".ok");

            try (FileWriter fw = new FileWriter(okFile);
                 BufferedWriter writer = new BufferedWriter(fw) ){
                writer.write(count+"");
                writer.flush();
            } catch (IOException e) {
                logger.error("生成OK文件失败");
                throw new RuntimeException(e);
            }
            logger.debug("传票合并处理完成");
            return RepeatStatus.FINISHED;
        };
    }
}
